package pe.com.bbva.efcap.servidor.servicio.impl;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pe.com.bbva.efcap.servidor.bean.rating.RatingBean;
import pe.com.bbva.efcap.servidor.bean.rating.RatingClienteBean;
import pe.com.bbva.efcap.servidor.bean.rating.RatingCuentaBean;
import pe.com.bbva.efcap.servidor.bean.rating.RatingPeriodoBean;
import pe.com.bbva.efcap.servidor.bean.rating.RatingValorCuentaBean;
import pe.com.bbva.efcap.servidor.dao.RatingDAO;
import pe.com.bbva.efcap.servidor.modelo.entidad.Rating;
import pe.com.bbva.efcap.servidor.servicio.RatingService;
import pe.com.bbva.efcap.servidor.util.PE21ServiceUtil;
import pe.com.grupobbva.grec.pe21.CtBodyRq;
import pe.com.grupobbva.grec.pe21.CtConGrecPe21Rq;
import pe.com.grupobbva.grec.pe21.CtConGrecPe21Rs;
import pe.com.grupobbva.grec.pe21.CtHeaderRq;

@Service
@Transactional(readOnly = true)
public class RatingServiceImpl implements RatingService{

	@Autowired
	private PE21ServiceUtil pe21ServiceUtil;
	
	@Autowired
	private RatingDAO ratingDAO;
	
	@Override	
	public RatingClienteBean obtenerClientePorRuc(String ruc) throws MalformedURLException{
		CtConGrecPe21Rq ctConGrecPe21Rq = new CtConGrecPe21Rq();
		CtBodyRq ctBodyRq = new CtBodyRq();
		ctBodyRq.setCodigoCentral("");
		ctBodyRq.setNumeroDocumentoIdentidad(ruc);
		ctBodyRq.setTipoDocumentoIdentidad("R");
		ctConGrecPe21Rq.setData(ctBodyRq);
		CtHeaderRq ctHeaderRq = new CtHeaderRq();
		ctHeaderRq.setOpcionAplicacion("00");
		ctHeaderRq.setTerminalContable("7%00");
		ctHeaderRq.setTerminalLogico("7%00");
		ctHeaderRq.setUsuario("R0001");
		ctConGrecPe21Rq.setHeader(ctHeaderRq);
		CtConGrecPe21Rs rs = pe21ServiceUtil.llamarPE21(ctConGrecPe21Rq);
		RatingClienteBean clienteBean = new RatingClienteBean();
		clienteBean.setCodigoCentral(rs.getData().getCodigoCentral());
		clienteBean.setNombreEmpresa(rs.getData().getNombreEmpresa());
		clienteBean.setRuc(rs.getData().getRUC());
		return clienteBean;
	}

	@Override	
	public RatingClienteBean obtenerClientePorCodigoCentral(String codigoCentral) throws MalformedURLException{
		CtConGrecPe21Rq ctConGrecPe21Rq = new CtConGrecPe21Rq();
		CtBodyRq ctBodyRq = new CtBodyRq();
		ctBodyRq.setCodigoCentral(codigoCentral);
		ctBodyRq.setNumeroDocumentoIdentidad("");
		ctBodyRq.setTipoDocumentoIdentidad("");
		ctConGrecPe21Rq.setData(ctBodyRq);
		CtHeaderRq ctHeaderRq = new CtHeaderRq();
		ctHeaderRq.setOpcionAplicacion("00");
		ctHeaderRq.setTerminalContable("7%00");
		ctHeaderRq.setTerminalLogico("7%00");
		ctHeaderRq.setUsuario("R0001");
		ctConGrecPe21Rq.setHeader(ctHeaderRq);
		CtConGrecPe21Rs rs = pe21ServiceUtil.llamarPE21(ctConGrecPe21Rq);
		RatingClienteBean clienteBean = new RatingClienteBean();
		clienteBean.setCodigoCentral(rs.getData().getCodigoCentral());
		clienteBean.setNombreEmpresa(rs.getData().getNombreEmpresa());
		clienteBean.setRuc(rs.getData().getRUC());
		return clienteBean;
	}
	
	@Override	
	public List<Rating> obtenerListaRating(String codigoCentral){		
		try {			
	        return ratingDAO.obtenerListaRatingPorCodigoCentral(codigoCentral);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	@Override
	public RatingBean obtenerRating(String codigoCentral, int numPeriodos){		
		try {
			List<Rating> lista = obtenerListaRating(codigoCentral);
			RatingBean rating = null;
			List<RatingPeriodoBean> periodos = null;
			RatingPeriodoBean periodo = null;
			List<RatingCuentaBean> cuentas = null;		
			RatingValorCuentaBean valor = null;
			boolean boCuentas = true;
			int cantidad = 0;
			for(Rating p : lista){
				valor = new RatingValorCuentaBean();
				valor.setMonto(p.getMonto().doubleValue());
				valor.setCodigoCuenta(p.getCuenta());
				if(rating == null){
					rating = new RatingBean();
					
					RatingClienteBean cliente = new RatingClienteBean();
					cliente.setCodigoCentral(p.getCodigoCentralCliente());
					cliente.setNombreEmpresa(p.getNombreEmpresa());
					rating.setCliente(cliente);
					
					periodos = new ArrayList<RatingPeriodoBean>();
					
					periodo = new RatingPeriodoBean();
					periodo.setPeriodo(obtenerPeriodo(p.getPeriodo()));
					periodo.setMesesEjercicio(p.getMesEjercicio().intValue());	
					periodo.setStatus(p.getEstado());
					periodo.setValorCuentas(new ArrayList<RatingValorCuentaBean>());
					periodo.getValorCuentas().add(valor);
					
					cuentas = new ArrayList<RatingCuentaBean>();
					RatingCuentaBean cuenta = new RatingCuentaBean();
					cuenta.setCodigoCuenta(p.getCuenta());
					cuenta.setDescripcionCuenta(p.getDescripcionCuenta());
					cuentas.add(cuenta);					
				}else{
					String periodoAux = obtenerPeriodo(p.getPeriodo());
					if(periodo.getPeriodo().equals(periodoAux) && periodo.getStatus().equals(p.getEstado())){ //mismo periodo
						periodo.getValorCuentas().add(valor);
						if(boCuentas){
							RatingCuentaBean cuenta = new RatingCuentaBean();
							cuenta.setCodigoCuenta(p.getCuenta());
							cuenta.setDescripcionCuenta(p.getDescripcionCuenta());
							cuentas.add(cuenta);
						}
					}else{ //seguiente periodo
						periodos.add(periodo);
						cantidad++;
						if(obtenerAnio(periodoAux).equals(obtenerAnio(periodo.getPeriodo()))){
							cantidad--;
						}
						if(cantidad == numPeriodos){
							break;
						}
						boCuentas = false;
						periodo = new RatingPeriodoBean();
						periodo.setPeriodo(obtenerPeriodo(p.getPeriodo()));
						periodo.setMesesEjercicio(p.getMesEjercicio().intValue());	
						periodo.setStatus(p.getEstado());
						periodo.setValorCuentas(new ArrayList<RatingValorCuentaBean>());
						periodo.getValorCuentas().add(valor);
					}
				}
			}
			if(rating != null){
				if(cantidad < numPeriodos){
					periodos.add(periodo);
				}
				rating.setPeriodos(periodos);
				rating.setCuentas(cuentas);
			}
			rating = priorizarPeriodos(rating);
			return rating;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	@Override
	@Transactional(readOnly = false)
	public boolean registrarRating(Rating rating){
		try{
			ratingDAO.guardar(rating);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}
	
	private RatingBean priorizarPeriodos(RatingBean ratingBean){
		String periodoAux = null;
		String status = null;		
		for(RatingPeriodoBean p : ratingBean.getPeriodos()){
			System.out.println(" - "+p+" ["+p.getValorCuentas().size()+"]");
		}
		System.out.println();
		List<RatingPeriodoBean> listaNueva = new ArrayList<RatingPeriodoBean>();
		int numPeriodosCerrados = 0;
		for(RatingPeriodoBean periodo : ratingBean.getPeriodos()){
			if(periodoAux == null){
				periodoAux = periodo.getPeriodo();
				status = periodo.getStatus();
				if(status.equals("A")||status.equals("F")){
					numPeriodosCerrados++;
				}
				listaNueva.add(periodo);
			} else {
				if(obtenerAnio(periodoAux).equals(obtenerAnio(periodo.getPeriodo()))){
					if(status.equals("A") && periodo.getStatus().equals("A")){
						;
					}else if(status.equals("A")){
						;
					}else if(periodo.getStatus().equals("A")){
						listaNueva.remove(listaNueva.size()-1);						
						listaNueva.add(periodo);
					}else if(status.equals("F") && periodo.getStatus().equals("F")){
						;
					}else if(status.equals("F")){
						;
					}else if(periodo.getStatus().equals("F")){
						listaNueva.remove(listaNueva.size()-1);
						listaNueva.add(periodo);
					}else{ //si el periodo anterior y el actual son G
						;
					}
				}else{
					listaNueva.add(periodo);
				}
				periodoAux = periodo.getPeriodo();
				status = periodo.getStatus();
				if(status.equals("A")||status.equals("F")){
					numPeriodosCerrados++;
				}
			}
		}
		if(numPeriodosCerrados <= 0){
			return null;
		}else{
			RatingBean r = new RatingBean();
			r.setCliente(ratingBean.getCliente());
			r.setCuentas(ratingBean.getCuentas());
			r.setPeriodos(listaNueva);
			return r;
		}
	}
	
	private String obtenerPeriodo(String fecha){
		return fecha.substring(6)+fecha.substring(3, 5);
	}
	
	private String obtenerAnio(String periodo){
		return periodo.substring(0, 4);
	}

}
